package com.dc.designPattern._3_prototype.deepClone;

import lombok.Data;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * Description: 演示深拷贝，拷贝对象
 * @author: gdc
 * @date: 2021/3/8
 * @version 1.0
 */
@Data
public class DeepProtoType implements Serializable, Cloneable{
	/**
	 * String 属性
	 */
	public String name;
	/**
	 * 引用类型
	 */
	public DeepCloneableTarget deepCloneableTarget;

	/**
	 * 深拷贝 - 方式 1 使用clone 方法
	 */
	@Override
	protected Object clone() throws CloneNotSupportedException {
		//这里完成对基本数据类型(属性)和String的克隆
		Object clone = super.clone();
		DeepProtoType deepProtoType = (DeepProtoType) clone;
		// 完成对引用对象的数据拷贝
		deepProtoType.setDeepCloneableTarget((DeepCloneableTarget)deepCloneableTarget.clone());
		return deepProtoType;
	}

	/**
	 * 深拷贝 - 方式2 通过对象的序列化实现 (推荐)
	 */
	public Object deepClone() {
		//创建流对象
		ByteArrayOutputStream bos = null;
		ObjectOutputStream oos = null;
		ByteArrayInputStream bis = null;
		ObjectInputStream ois = null;

		try {
			//序列化
			bos = new ByteArrayOutputStream();
			oos = new ObjectOutputStream(bos);
			oos.writeObject(this); //当前这个对象以对象流的方式输出

			//反序列化
			bis = new ByteArrayInputStream(bos.toByteArray());
			ois = new ObjectInputStream(bis);
			DeepProtoType copyObj = (DeepProtoType)ois.readObject();
			return copyObj;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			//关闭流
			try {
				bos.close();
				oos.close();
				bis.close();
				ois.close();
			} catch (Exception e2) {
				System.out.println(e2.getMessage());
			}
		}
	}

}
